package player 
{
	import collisions.Body;
	import collisions.LinkedList;
	import collisions.PixelPerfectCollisionDetection;
	import collisions.QuadTree;
	import collisions.World;
	import enemies.Enemy;
	import entities.Entity;
	import flash.display.Sprite;
	import flash.geom.Point;
	import recorder.EntityStateRecorder;
	import recorder.IRecorder;
	import recorder.RecordData;
	import renderers.Renderer;
	
	/**
	 * ...
	 * @author Gareth Williams
	 */
	
	public class Player extends Entity
	{
		public var driver:IRecorder;
		public var controller:IController;
		public var weaponStrength:int = 10;//this could be changed by pickups
		
		//state properties recorder
		private var _recorder:EntityStateRecorder;
		
		public function Player(x:Number = 0, y:Number = 0, radius:Number = 10) 
		{
			collisionGroup = Constants.PLAYER_GROUP;
			
			super(x, y, radius);
			_recorder = new EntityStateRecorder(this);
			this.rotation = Math.PI;  
		}
		override public function destructor():void 
		{
			super.destructor();
		}
		//on update move to last recorded position at t plus gamepad input 
		override public function update():void
		{
			//apply recorded states
			_recorder.update();
			var stateData:RecordData = _recorder.retrieveDataAt(Main.timestep);
			stateData.applyTo(this);
			
			//death animation
			if (false == this.isAlive)
			{
				Sprite(this.graphic).alpha = 0.5;
			}
			else
			{
				Sprite(this.graphic).alpha = 1.0;
			}
			
			if (false == this.isAlive) return;//exit early
			
			var padDirection:Point;
			var padRotation:Number;
			var isFiring:Boolean;
			try
			{
				padDirection = controller.getDirection();
				padRotation = controller.getAngle();
				isFiring = controller.getFireButton();
			}
			catch (e:TypeError)
			{
				padDirection = new Point();
				padRotation = 0;
				isFiring = false;
			}
			
			//no joypad input
			if (padDirection.x === 0 && padDirection.y === 0)
			{
				var previousPosition:Point = new Point(this.x, this.y);
				
				//visitor (previous recorded position)
				var spatialData:RecordData = driver.retrieveDataAt(Main.timestep);
				spatialData.applyTo(this);
			}
			else
			{
				this.x += padDirection.x * (this.speed * Main.timeIncrement);
				this.y += padDirection.y * (this.speed * Main.timeIncrement);
				//this.viewCone.angleInRadians = this.rotation = padRotation - Constants.HALF_PI;
				//this.rotation = padRotation - Constants.HALF_PI;
			}
			
			//fire button
			if (isFiring)
			{
				Main.addBullet(new Bullet(this.rotation, this.x, this.y, 2));
				//Main.addBullet(BulletPool.checkOut((this.rotation, this.x, this.y, 2)));
			}
		}
		public function receiveDamage(amount:int):void
		{
			this.percentHealth -= amount;
			this.graphic.doHitAnimation();
			this.graphic.doHealthAnimation(percentHealth);
			if (true == checkWhetherDead())
			{
				//this.isAlive = false; for the purpose of the demo
				//this.graphic.doDeathAnimation();
				Sprite(this.graphic).alpha = 0.5;
			}
		}
		override public function processCollisionWith(collider:Body):void
		{
			//ignore same-type collisions with previous incarnations
			if (collider is Player) return;
			
			this.isAlive = false;
			//this.graphic.doDeathAnimation();
		}
		//helpers
		private function checkWhetherDead():Boolean
		{
			return percentHealth <= 0;
		}
	}
}